package com.jie.aspect;

import com.jie.annotation.OptLog;
import com.jie.annotation.RedisCount;
import com.jie.dto.RedisCountDTO;
import com.jie.entity.OperationLog;
import com.jie.response.RespBean;
import com.jie.utils.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HyperLogLogOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 将每个统计次数封装为注解，在切面中统计访问次数
 * @Author: 杰
 * @Project :net-disk
 * @DateTime: 2024/4/21 13:58
 **/
@Aspect
@Component
public class RedisCountAspect {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /**
     * 设置统计位置 count+1 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.jie.annotation.RedisCount)")
    public void optCountPointCut() {}
    @Transactional
    @AfterReturning(value = "optCountPointCut()", returning = "values")
    public void save(JoinPoint joinPoint, Object values) {
        //获取注解
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
       //获取注解的key
        String key = signature.getMethod().getAnnotation(RedisCount.class).optSportType();
        //采用HyperLogLog算法统计，可以接受一定的统计误差，但是计算资源更少
        // 统计访问次数
        HyperLogLogOperations<String, String> count = redisTemplate.opsForHyperLogLog();
        //获取当前对象，将当前对象放入当前count内部
        Integer userId = UserUtils.getLoginUser().getId();
       //将当前对象转换为RedisCountDTO只需要获取id就可以
        RespBean respBean=(RespBean) values;
        RedisCountDTO redisCountDTO= (RedisCountDTO) respBean.getData();
        //存入redis中
        count.add(key+redisCountDTO.getId(), String.valueOf(userId));
    }
}
